package com.ideaaedi.springcloud.jd.user.controller.sys;

import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import com.ideaaedi.springcloud.jd.commonds.entity.PageInfo;
import com.ideaaedi.springcloud.jd.commonds.entity.Result;
import com.ideaaedi.springcloud.jd.commonds.entity.user.vo.req.SysMenuAddReqVO;
import com.ideaaedi.springcloud.jd.commonds.entity.user.vo.req.SysMenuBatchAddReqVO;
import com.ideaaedi.springcloud.jd.commonds.entity.user.vo.req.SysMenuBindApiReqVO;
import com.ideaaedi.springcloud.jd.commonds.entity.user.vo.req.SysMenuListAllVO;
import com.ideaaedi.springcloud.jd.commonds.entity.user.vo.req.SysMenuListReqVO;
import com.ideaaedi.springcloud.jd.commonds.entity.user.vo.req.SysMenuUpdateReqVO;
import com.ideaaedi.springcloud.jd.commonds.entity.user.vo.resp.SysApiListRespVO;
import com.ideaaedi.springcloud.jd.commonds.entity.user.vo.resp.SysMenuDetailRespVO;
import com.ideaaedi.springcloud.jd.commonds.entity.user.vo.resp.SysMenuListRespVO;
import com.ideaaedi.springcloud.jd.commonspring.util.JdContextUtil;
import com.ideaaedi.springcloud.jd.user.service.SysMenuApiReService;
import com.ideaaedi.springcloud.jd.user.service.SysMenuService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.List;

/**
 * 系统 - 菜单
 *
 * @author <font size = "20" color = "#3CAA3C"><a href="https://gitee.com/JustryDeng">JustryDeng</a></font> <img src="https://gitee.com/JustryDeng/shared-files/raw/master/JustryDeng/avatar.jpg" />
 * @since 2021.0.1.A
 */
@RestController
@ApiSort(value = 6)
@RequestMapping("/sys-menu")
@Api(value = "系统-菜单", tags = {"系统-菜单"})
public class SysMenuController {
    
    @Resource
    private SysMenuService sysMenuService;
    
    @Resource
    private SysMenuApiReService sysMenuApiReService;
    
    /**
     * 新增
     *
     * @param req
     *         参数
     *
     * @return 新增的菜单详情
     */
    @PostMapping("/add")
    @ApiOperation(value = "新增")
    @ApiOperationSupport(order = 1)
    public Result<SysMenuDetailRespVO> add(@Validated @RequestBody SysMenuAddReqVO req) {
        return Result.success(sysMenuService.add(req, true));
    }
    
    /**
     * 批量新增
     *
     * @param req
     *         参数
     *
     * @return 请求结果
     */
    @PostMapping("/batch-add")
    @ApiOperation(value = "批量新增")
    @ApiOperationSupport(order = 2)
    public Result<Void> batchAdd(@Validated @RequestBody SysMenuBatchAddReqVO req) {
        sysMenuService.batchAdd(req);
        return Result.success();
    }
    
    /**
     * 删除
     *
     * @param menuId 部门id
     *
     * @return 删除了的菜单详情
     */
    @ApiOperation(value = "删除")
    @ApiOperationSupport(order = 3)
    @DeleteMapping("/delete/{menuId}")
    public Result<SysMenuDetailRespVO> delete(@ApiParam(value = "部门id", required = true)
                                              @NotNull(message = "menuId不能为空") @PathVariable("menuId") Long menuId) {
        return Result.success(sysMenuService.delete(menuId));
    }
    
    /**
     * 删除所有菜单（自动跳过系统内置菜单）
     *
     * @param tenant 租户值（不指定则自动获取）
     *
     * @return 请求是否成功
     */
    @ApiOperationSupport(order = 4)
    @DeleteMapping("/delete-by-tenant")
    @ApiParam(value = "租户值（不指定则自动获取）")
    @ApiOperation(value = "删除所有菜单（自动跳过系统内置菜单）")
    public Result<Void> deleteByTenant(@RequestParam(value = "tenant", required = false) String tenant) {
        sysMenuService.deleteByTenant(tenant);
        return Result.success();
    }
    
    /**
     * 更新
     *
     * @param req
     *         参数
     *
     * @return 更新后的菜单详情
     */
    @PutMapping("/update")
    @ApiOperation(value = "更新")
    @ApiOperationSupport(order = 3)
    public Result<SysMenuDetailRespVO> update(@Validated @RequestBody SysMenuUpdateReqVO req) {
        return Result.success(sysMenuService.update(req));
    }
    
    /**
     * 查询当前用户可见的菜单
     *
     * @param req 参数
     *
     * @return 菜单列表
     */
    @PostMapping("/list")
    @ApiOperationSupport(order = 4)
    @ApiOperation(value = "查询当前用户可见的菜单")
    public Result<PageInfo<SysMenuListRespVO>> list(@Validated @RequestBody SysMenuListReqVO req) {
        req.setUserId(JdContextUtil.currUserIdNonNull());
        return Result.success(sysMenuService.list(req));
    }
    
    /**
     * 查询（当前业务租户下）所有菜单
     *
     * @param req
     *         参数
     *
     * @return 菜单列表
     */
    @PostMapping("/list-all")
    @ApiOperationSupport(order = 5)
    @ApiOperation(value = "查询（当前业务租户下）所有菜单")
    public Result<PageInfo<SysMenuListRespVO>> listAll(@Validated @RequestBody SysMenuListAllVO req) {
        return Result.success(sysMenuService.listAll(req));
    }
    
    /**
     * 详情
     *
     * @param menuId 菜单id
     *
     * @return 菜单详情
     */
    @ApiOperation(value = "详情")
    @ApiOperationSupport(order = 6)
    @GetMapping("/detail/{menuId}")
    public Result<SysMenuDetailRespVO> detail(@ApiParam(value = "菜单id", required = true)
                                              @NotNull(message = "menuId不能为空") @PathVariable("menuId") Long menuId) {
        return Result.success(sysMenuService.detail(menuId));
    }
    
    /**
     * 给菜单绑定api
     *
     * @param req
     *         请求模型
     *
     * @return 菜单绑定的api集合
     */
    @PostMapping("/bind-api")
    @ApiOperationSupport(order = 7)
    @ApiOperation(value = "给菜单绑定api")
    public Result<List<SysApiListRespVO>> bindApi(@Validated @RequestBody SysMenuBindApiReqVO req) {
        return Result.success(sysMenuApiReService.bindApi(req));
    }
    
    /**
     * 查询菜单拥有的api
     *
     * @param menuId 菜单id
     *
     * @return api集合
     */
    @GetMapping("/query-api/{menuId}")
    @ApiOperationSupport(order = 8)
    @ApiOperation(value = "查询菜单绑定的api")
    public Result<List<SysApiListRespVO>> queryApi(@ApiParam(value = "菜单id", required = true)
                                                   @NotNull(message = "menuId不能为空") @PathVariable("menuId") Long menuId) {
        return Result.success(sysMenuApiReService.queryBindApi(menuId));
    }
}
